package cn.silver.module.configuration.service.impl;

import cn.silver.framework.core.constant.CacheNames;
import cn.silver.framework.core.enums.SystemStatusEnums;
import cn.silver.framework.core.exception.ServiceException;
import cn.silver.framework.core.model.DictModel;
import cn.silver.framework.core.utils.StreamUtils;
import cn.silver.framework.mybatis.service.impl.BusServiceImpl;
import cn.silver.framework.redis.utils.RedisUtils;
import cn.silver.module.configuration.bean.DictBean;
import cn.silver.module.configuration.bean.DictItemBean;
import cn.silver.module.configuration.domain.SysDict;
import cn.silver.module.configuration.domain.SysDictItem;
import cn.silver.module.configuration.mapper.SysDictMapper;
import cn.silver.module.configuration.param.DictParam;
import cn.silver.module.configuration.service.ISysDictItemService;
import cn.silver.module.configuration.service.ISysDictService;
import cn.silver.module.configuration.service.DictService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 字典 业务层处理
 *
 * @author Silver Zhou
 */
@Service
@RequiredArgsConstructor
public class SysDictServiceImpl extends BusServiceImpl<SysDictMapper, SysDict, DictParam, DictBean> implements ISysDictService, DictService {

    private final ISysDictItemService itemService;

    @Override
    public void init() {
        this.loadCache();
    }

    @Override
    public void loadCache() {
        List<DictItemBean> beans = this.itemService.selectList(new LambdaQueryWrapper<SysDictItem>().eq(SysDictItem::getStatus, SystemStatusEnums.NORMAL.getCode()));
        StreamUtils.groupByKey(beans, DictItemBean::getType).forEach((key, value) -> {
            RedisUtils.setCacheList(CacheNames.SYS_DICT, key, value.stream().map(DictItemBean::convertModel).toList());
        });
    }

    /**
     * 根据字典类型查询字典数据
     *
     * @param dictType 字典类型
     * @return 字典数据集合信息
     */
    @Override
    public List<DictItemBean> selectDictDataByType(String dictType) {
        return this.itemService.selectList(new LambdaQueryWrapper<SysDictItem>().eq(SysDictItem::getType, dictType));
    }

    @Override
    public List<DictModel> getDictModelByCode(String dictType) {
        List<DictModel> models = RedisUtils.getCacheList(CacheNames.SYS_DICT, dictType);
        if (CollectionUtils.isEmpty(models)) {
            List<DictItemBean> beans = this.itemService.selectList(new LambdaQueryWrapper<SysDictItem>().eq(SysDictItem::getType, dictType));
            models = CollectionUtils.isNotEmpty(beans) ? beans.stream().map(DictItemBean::convertDict).toList() : Collections.emptyList();
            RedisUtils.setCacheList(CacheNames.SYS_DICT, dictType, models);
        }
        return models;
    }

    @Override
    public Map<String, String> getDictMapByCode(String dictType) {
        List<DictModel> list = getDictModelByCode(dictType);
        return StreamUtils.toMap(list, DictModel::getValue, DictModel::getLabel);
    }

    /**
     * 新增保存字典类型信息
     *
     * @param model 字典类型信息
     * @return 结果
     */
//    @Override
//    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#model.code")
//    public boolean insert(DictBean model) {
//        long exist = this.selectExist(model);
//        if (exist > 0) {
//            throw new ServiceException(ResultEnum.DATA_ERROR_EXIST.getCode(), "字典名称或编码已存在");
//        }
//        SysDict exists = StringUtils.isNotBlank(model.getId()) ? this.baseMapper.selectById(model.getId()) : null;
//        SysDict entity = MapstructUtils.convert(model, getEntityClass());
//        if (exists != null) {
//            return SqlHelper.retBool(this.baseMapper.updateById(entity));
//        } else {
//            return SqlHelper.retBool(this.baseMapper.insert(entity));
//        }
//    }
//
//    /**
//     * 修改保存字典类型信息
//     *
//     * @param model 字典类型信息
//     * @return 结果
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
//    public boolean update(DictBean model) {
//        long exist = this.selectExist(model);
//        if (exist > 0) {
//            throw new ServiceException(ResultEnum.DATA_ERROR_EXIST.getCode(), "字典名称或编码已存在");
//        }
//        return SqlHelper.retBool(baseMapper.updateById(MapstructUtils.convert(model, SysDict.class)));
//    }

    /**
     * 批量删除字典类型信息
     *
     * @param dictIds 需要删除的字典ID
     */
    @Override
    public void deleteBatch(Collection<String> dictIds) {
        List<DictBean> models = this.selectByIds(dictIds);
        Map<String, String> modelMap = StreamUtils.toMap(models, DictBean::getCode, DictBean::getName);
        List<String> codes = models.stream().map(DictBean::getCode).toList();
        List<DictItemBean> items = this.itemService.selectList(new LambdaQueryWrapper<SysDictItem>().in(SysDictItem::getType, codes));
        if (CollectionUtils.isNotEmpty(items)) {
            throw new ServiceException(String.format("%1$s已分配,不能删除", items.stream().map(DictItemBean::getType).distinct()
                    .map(modelMap::get).collect(Collectors.joining(","))));
        }
        baseMapper.deleteByIds(dictIds);
    }

    /**
     * 重置字典缓存数据
     */
    @Override
    public void clearCache() {
        RedisUtils.deleteKeys(CacheNames.SYS_DICT);
    }
}
